﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace ProceduralCity.Utility
{
    static class Maths
    {
        static Random rand = new Random();

        /// <summary>
        /// Generates a random number within a percentage of a specified number.
        /// </summary>
        /// <param name="near">The base starting point.</param>
        /// <param name="within">The percent by which the output can vary from the base. 1.0f is 100%.</param>
        /// <returns></returns>
        public static float RandomNear(float near, float withinPercent)
        {
            float delta = near * withinPercent;
            float low = near - delta;
            float high = near + delta;
            float result = RandomBetween(low, high);
            return result;
        }

        /// <summary>
        /// Generates a random number between the two provided.
        /// </summary>
        public static float RandomBetween(float a, float b)
        {
            float result = MathHelper.Lerp(a, b, (float)rand.NextDouble());
            return result;
        }

        public static Vector3 RandomBetween(Vector3 a, Vector3 b)
        {
            Vector3 result = new Vector3(
                RandomBetween(a.X, b.X),
                RandomBetween(a.Y, b.Y),
                RandomBetween(a.Z, b.Z)
            );
            return result;
        }

        /// <summary>
        /// Returns the input rounded to the nearest multiple of the provided value.
        /// </summary>
        /// <param name="multipleOf">If 0, the input is returned unchanged.</param>
        public static float NearestMultiple(float input, float multipleOf)
        {
            if (multipleOf == 0)
                return input;

            float result = (float)(Math.Round(input / multipleOf) * multipleOf);
            return result;
        }

        public static Vector3 NearestMultiple(Vector3 input, Vector3 multipleOf)
        {
            Vector3 result = new Vector3(
                NearestMultiple(input.X, multipleOf.X),
                NearestMultiple(input.Y, multipleOf.Y),
                NearestMultiple(input.Z, multipleOf.Z)
            );
            return result;
        }

        public static Vector3 Floor(Vector3 input)
        {
            Vector3 result = new Vector3(
                (float)Math.Floor(input.X),
                (float)Math.Floor(input.Y),
                (float)Math.Floor(input.Z)
            );
            return result;
        }
    }
}
